#include "DataFrame.h"
#include<iostream>
#include<cstdlib>
#include"net_tool.h"
#include<unistd.h>
#include<string.h>
DataFrame::DataFrame() {}
const unsigned char* DataFrame::getFrame() {
    return this->frame;
}

bool DataFrame::readFrame(SOCKET_T socket_fd)  {
    int ret = recv(socket_fd, (char *)this->frame, 9, MSG_WAITALL) ;
    if ( ret != FRAME_LENGTH) {
        if ( ret == -1 ) {
            throw SocketException("Read frame error: -1");
        } else {
            for (int i = 0; i < ret; i++) {
                printf("%.2x ",this->frame[i]);
            }
            throw SocketException("Frame format error");
        }
    } else {
        this->parseFrame();
    }
    return true;
}

void DataFrame::printFrameInfo() {
    printf("flag: %.2x\nlength: %lld\n", this->flag, this->length);
}


bool DataFrame::sendFrame(SOCKET_T socket_fd, unsigned char flag, unsigned long long length) 
    {
    this->buildFrame(flag, length);
    ssize_t ret = send(socket_fd, (const char*)this->frame, FRAME_LENGTH, 0);
    if (ret != FRAME_LENGTH) {
        #ifdef __MINGW32__
        std::cout << socket_fd << std::endl;
        throw SocketException(std::string("Frame send error: ") + std::to_string(WSAGetLastError()));
        #else
        throw SocketException(std::string("Frame send error: ") + strerror(errno));
        #endif
    } else {
        return true;
    }
}

bool DataFrame::sendFrame(SOCKET_T socket_fd)
     {
    this->sendFrame(socket_fd, this->flag, this->length);
    return true;
}

bool DataFrame::parseFrame(const unsigned char data[FRAME_LENGTH] ) {
    memcpy(&this->flag, data, FRAME_FLAG_LENGTH);
    memcpy(&this->length, data + FRAME_FLAG_LENGTH, FRAME_LENGTH_LENGTH);
    // this->length = ntohll(this->length);
    return true;
}

bool DataFrame::parseFrame() {
    return this->parseFrame(this->frame);
}

bool DataFrame::buildFrame(unsigned char flag, unsigned long long length) {
    this->flag = flag;
    this->length = length;
    this->frame[0] = flag;
    memcpy(this->frame + 1, &length, FRAME_LENGTH_LENGTH);
    return true;
}